import { useState, useCallback, useEffect } from 'react';
import { type AxiosRequestConfig, AxiosError } from 'axios';
import { request } from '../utils/request';

// 定义hook返回类型
interface UseRequestResult<T> {
    data: T | null;
    loading: boolean;
    error: AxiosError | null;
    run: (config?: AxiosRequestConfig) => Promise<T>;
    refresh: () => Promise<T>;
    mutate: (data: T) => void;
}

/**
 * 通用请求Hook
 * @param config 请求配置
 * @param options 额外选项
 * @returns 请求结果
 */
export const useRequest = <T = any>(
    config: AxiosRequestConfig,
    options?: {
        immediate?: boolean; // 是否立即执行
    }
): UseRequestResult<T> => {
    const [data, setData] = useState<T | null>(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<AxiosError | null>(null);
    const [currentConfig, setCurrentConfig] = useState(config);

    // 执行请求
    const run = useCallback(async (newConfig?: AxiosRequestConfig) => {
        setLoading(true);
        setError(null);
        try {
            const finalConfig = { ...currentConfig, ...newConfig };
            const response = await request(finalConfig);
            setData(response.data);
            setCurrentConfig(finalConfig);
            return response.data;
        } catch (err) {
            setError(err as AxiosError);
            throw err;
        } finally {
            setLoading(false);
        }
    }, [currentConfig]);

    // 刷新请求
    const refresh = useCallback(() => run(), [run]);

    // 手动更新数据
    const mutate = useCallback((newData: T) => {
        setData(newData);
    }, []);

    // 立即执行请求
    useEffect(() => {
        if (options?.immediate !== false) {
            run();
        }
    }, [run, options?.immediate]);

    return {
        data,
        loading,
        error,
        run,
        refresh,
        mutate
    };
};